home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
134_01
/
cprofil2.csm
< prev
next >
Wrap
Text File
|
1985-08-19
|
12KB
|
511 lines
; BDS `C' Profiler - Assembly Language portion
; Copyright (c) 1983 by Kevin B. Kenny.
; Released to the BDS `C' Users' Group for non-commercial distribution.
; This file contains the assembly-language functions needed by the BDS
; `C' profiler program.
; Functions included:
; superv chain nexecl
MACLIB "BDS"
SECSIZ EQU 128 ; Disk sector size in CP/M
; SUPERV -- Run-time supervisor for profiler
; The folowing function must *NOT* be called from the 'C' program. It
; contains the code for the profiler which is loaded into high memory while
; the profiled program is executing. The code intercepts the RST 6 operations
; that delineate the source statements, and accumulates the totals. Upon any
; attempt to warm-boot CP/M, the supervisor reloads CPROFILE and transfers to
; it to do the analysis and print the results.
FUNCTION superv
; The following locations are fixed offsets from the beginning of SUPERV,
; used for communication with CPROFILE itself. Their order and size must not
; be changed without changing CPROFILE as well.
START jmp $-$ ; Imitation BDOS entry to mark top of
; available memory. Transfers to real
; BDOS for processing.
db 'cprofile', 0 ; Signature, used by CPROFILE to detect
; that he's been reloaded.
jmp preinit ; Transfer to preliminary init code.
jmp fakeboot ; Transfer to artificial warmboot
; routine.
dw suptop ; Size of the supervisor
dw table ; Pointer to first profile table entry.
tbnext:
dw table ; Pointer to next available slot for
; profile table entry.
realboot:
dw $-$ ; BIOS warm-boot entry before CPROFILE
; was invoked.
cmdline:
ds 128 ; CPROFILE command tail, used to reload
; CPROFILE.
; Come here on preliminary initialization after reading the target
; program into the lower TPA. Dummy up a CCP stack pointer, clobber the
; "khack" portion of C.CCC initialization, and go re-initialize C.CCC for
; the target program.
preinit:
lxi sp, preinit ; Fake a stack pointer for target
mvi a, 0C9h ; (RET) ; Save a return instruction in "khack"
sta khack
mvi a, 0C3h ; (JMP) ; Set up the RST 6 vector for profiling
sta 00030h
lxi h, rst6ent
shld 00031h
mvi c, pstrng ; Print message that we got here.
lxi d, entrmsg
call start
call tpa ; Go enter the user program.
jmp fakeboot ; Reload profiler when program finishes
; Come here on a RST 6 instruction within the target program. Accumulate
; the profile data.
rst6ent:
push h ; Save all registers
push d
push b
push psw
lxi h, 8 ; Increment return address around
dad sp ; line and statement information.
mov c,m
inx h
mov b,m
inx b
inx b
mov m,b
dcx h
mov m,c
dcx h
dcx b
dcx b ; Get original PC back
lhld tbnext
xchg ; Get start and end of profile table
lxi h, table
ploop: mov a, d ; If at end of table, go to NOTFND
cmp h
jnz notdone
mov a,e
cmp l
jz notfnd
notdone:
mov a,c ; If the PC in table doesn't match ours
cmp m ; go to NOTHERE(2) to advance to next
jnz nothere ; table entry.
inx h
mov a,b
cmp m
jnz nothere2
lxi b,4 ; Point HL to least significant byte of
dad b ; execution count
mov a,m
adi 1 ; Increment trip count
mov m,a
dcx h
mov a,m
aci 0
mov m,a
dcx h
mov a,m
aci 0
mov m,a
dcx h
mov a,m
aci 0
mov m,a
jmp finis ; Done with this RST 6
nothere:
inx h ; Advance to next table entry
nothere2:
inx h
inx h
inx h
inx h
inx h
jmp ploop
notfnd:
lda start+1
sui 6
sub l ; Entry not found in table. Make sure
lda start+2 ; there's space for it.
sbb h
jnc addent
mvi c,pstrng ; There isn't; complain and abort.
lxi d,fullmsg
call start
jmp base
addent:
mov m,c ; Add an entry to table; first the PC,
inx h
mov m,b
inx h
xra a ; then a count of 1.
mov m,a
inx h
mov m,a
inx h
mov m,a
inx h
inr a
mov m,a
inx h
shld tbnext ; Advance table end.
finis:
pop psw
pop b
pop d
pop h
ret ; Return to target program
; Come here on a call to BIOS warmboot function or BDOS function 0.
; Reload CPROFILE in the lower TPA, and perform the analysis of the profile
; data gathered up in the TABLE area.
fakeboot:
lhld realboot ; Reset BIOS warm-boot transfer to
xchg ; its original value.
lhld base+1
inx h
mov m,e
inx h
mov m,d
mvi c, pstrng ; Print a message to announce what's
lxi d, rlodmsg ; happening
call bdos
lxi d, tbuff ; Move command tail back in place
lxi h, cmdline
mvi c, 128
mtail: mov a, m
stax d
inx h
inx d
dcr c
jnz mtail
mvi c, openc ; Re-open CPROFILE.COM
lxi d, cprfcb
call bdos
inr a
jz openerr
xra a
sta cprfcb+32 ; Zero current record index.
rloop: lhld loadorg ; Get present loading origin
xchg
lxi h, secsiz ; Bump it by a sector for next time
dad d
shld loadorg
mvi c, sdma ; Set DMA pointer to loading origin
call bdos
mvi c, reads ; Read in a sector of CPROFILE.COM
lxi d, cprfcb
call bdos
ora a
jz rloop ; Continue reading until EOF
mvi c, closec ; Close CPROFILE.COM
lxi d, cprfcb
call bdos
mvi c, sdma ; Reset default DMA address
lxi d, tbuff
call bdos
jmp tpa ; Go enter reloaded copy of CPROFILE
openerr: ; Couldn't reopen CPROFILE.COM
mvi c, pstrng
lxi d, opermsg
call bdos
jmp base
entrmsg:
db '<<< Executing target program. >>>', CR, LF, '$'
fullmsg:
db CR, LF, '<<< Profile table is full. Abandoning program. >>>'
db '$'
rlodmsg:
db CR, LF, '<<< Reloading CPROFILE. >>>', CR, LF, '$'
opermsg:
db 'Can''t open CPROFILE.COM; CPROFILE abandoned.$'
loadorg:
dw tpa ; Loading origin of CPROFILE
cprfcb:
db 0, 'CPROFILE', 'COM', 0, 0, 0, 0
dw 0, 0, 0, 0, 0, 0, 0, 0 ; FCB for CPROFILE.COM
db 0, 0, 0, 0
table: ; Profile table starts here.
suptop: ; Top of the supervisor
ENDFUNC superv
; CHAIN
; The following function is used to chain to the program being
; analyzed. It takes the following calling sequence:
; chain (argc, argv, entry);
; where argc and argv are the usual command parameters (argv [0] is the
; name of the .COM file to load), and entry is the entry address of the
; loaded program. Entry would be 0x100 under normal circumstances, but
; the CPROFILE run-time supervisor has a few unusual entry tasks to do.
FUNCTION chain
EXTERNAL nexecl
call arghak ; Get the arguments
push b
lhld arg3
push h ; Push the entry point address
lxi h,0
push h ; Push the argv fence
lhld arg1
xchg ; Get DE = arg count, HL -> argv end
lhld arg2
dad d
dad d
loop: dcx h
mov a,m
dcx h ; Place an argument on stack
push h
mov l,m
mov h,a
xthl
dcx d ; Count down arguments until finished
mov a, d
ora e
jnz loop
done: call nexecl ; Go call NExecl to load the program
jmp base ; NEXECL return is a disaster.
ENDFUNC
; NEXECL
; Derived from the EXECL function in the BDS `C' system library
; (DEFF2C.CSM) copyright (c) 1983 by Leor Zolman. Used by permission.
; This function is identical to the EXECL function in the BDS 'C'
; system library with the single exception that it accepts an additional
; argument following the list of command line arguments and the zero
; terminator. This argument is the address of a preinitialization entry
; point to which the loader will transfer instead of entering the TPA
; directly at 0x0100.
FUNCTION nexecl
call arghak
push b
lhld arg1
xchg
lxi h,-60 ;compute &nfcb for use here
dad sp
push h ; save for much later (will pop into BC)
push h ;make a few copies for local use below
push h
call setfcu ;set up COM file for execl-ing
lda usrnum
call setusr ;set destination user area
pop h ;get new fcb addr
lxi b,9 ;set extension to COM
dad b
mvi m,'C'
inx h
mvi m,'O'
inx h
mvi m,'M'
pop d ;get new fcb addr again
mvi c,openc ;open the fi